import Cesium, { Credit, Event, Rectangle, TextureMagnificationFilter, TextureMinificationFilter, TilingScheme } from '../Ces/Cesium';

class WeVectorImageryLayerProvider {
  private _url: string;
  defaultAlpha: number | undefined;
  defaultNightAlpha: number | undefined;
  defaultDayAlpha: number | undefined;
  defaultBrightness: number | undefined;
  defaultContrast: number | undefined;
  defaultHue: number | undefined;
  defaultSaturation: number | undefined;
  defaultGamma: number | undefined;
  defaultMinificationFilter: TextureMinificationFilter | undefined;
  defaultMagnificationFilter: TextureMagnificationFilter | undefined;
  private _errorEvent: Event;
  private _readyPromise: any//Cesium.Deferred;
  private _credit: Credit | undefined;
  private _tileWidth: number;
  private _tileHeight: number;
  private _maximumLevel: number;
  private _minimumLevel: number;
  private _tilingScheme: TilingScheme;
  private _ready: boolean;
  private render: any;
  createComputeCommand

  constructor(options: any) {
    options = options?? Cesium.Frozen.EMPTY_OBJECT

    this._url = options.url;
    this.defaultAlpha = undefined;
    this.defaultNightAlpha = undefined;
    this.defaultDayAlpha = undefined;
    this.defaultBrightness = undefined;
    this.defaultContrast = undefined;
    this.defaultHue = undefined;
    this.defaultSaturation = undefined;
    this.defaultGamma = undefined;
    this.defaultMinificationFilter = undefined;
    this.defaultMagnificationFilter = undefined;
    this._errorEvent = new Cesium.Event();
    this._readyPromise = Cesium.defer();

    let credit = options.credit;
    if (typeof credit === 'string') {
      credit = new Cesium.Credit(credit);
    }
    this._credit = credit;

    this._tileWidth = options.tileWidth || 256;
    this._tileHeight = options.tileHeight || 256;
    this._maximumLevel = options.maximumLevel || 14;
    this._minimumLevel = options.minimumLevel || 2;

    this._tilingScheme = options.tilingScheme?? new Cesium.WebMercatorTilingScheme()
    this._ready = false;

    this.render = options.render;
    this.render.readyPromise.then((valid: boolean) => {
      if (valid === undefined) valid = true;
      this._ready = valid;
    });

    const createComputeCommand = options.createComputeCommand??this.render.createComputeCommand
    if (createComputeCommand) {
      this.createComputeCommand = (p1: any, p2: any, p3: any, p4: any) => createComputeCommand(p1, p2, p3, p4);
    }
  }

  get url(): string {
    return this._url;
  }

  set url(value: string) {
    this._url = value;
  }

  get proxy(): undefined {
    return undefined;
  }

  get tileWidth(): number {
    if (!this._ready) {
      throw new Cesium.DeveloperError('tileWidth must not be called before the imagery provider is ready.');
    }
    return this._tileWidth;
  }

  get tileHeight(): number {
    if (!this._ready) {
      throw new Cesium.DeveloperError('tileHeight must not be called before the imagery provider is ready.');
    }
    return this._tileHeight;
  }

  get maximumLevel(): number | undefined {
    if (!this._ready) {
      throw new Cesium.DeveloperError('maximumLevel must not be called before the imagery provider is ready.');
    }
    return this._maximumLevel;
  }

  get minimumLevel(): number {
    if (!this._ready) {
      throw new Cesium.DeveloperError('minimumLevel must not be called before the imagery provider is ready.');
    }
    return this._minimumLevel;
  }

  get tilingScheme(): TilingScheme {
    if (!this._ready) {
      throw new Cesium.DeveloperError('tilingScheme must not be called before the imagery provider is ready.');
    }
    return this._tilingScheme;
  }

  get rectangle(): Rectangle {
    return this._tilingScheme.rectangle;
  }

  get tileDiscardPolicy(): undefined {
    if (!this._ready) {
      throw new Cesium.DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.');
    }
    return undefined;
  }

  get errorEvent(): Event {
    return this._errorEvent;
  }

  get ready(): boolean {
    return this._ready;
  }

  get readyPromise(): Promise<boolean> {
    return this._readyPromise.promise;
  }

  get credit(): Credit | undefined {
    return this._credit;
  }

  get hasAlphaChannel(): boolean {
    return true;
  }

  getTileCredits(x: number, y: number, level: number): Credit[] | undefined {
    return undefined;
  }

  requestImage(x: number, y: number, level: number, request?: any): Promise<HTMLImageElement | HTMLCanvasElement> | undefined {
    if (!this._ready) {
      throw new Cesium.DeveloperError('requestImage must not be called before the imagery provider is ready.');
    }
    return this.render.requestImage(x, y, level, request, this);
  }
}

export default WeVectorImageryLayerProvider;
